﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using CommonDevelop.Ioc;
using CommonFP;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace CommonDevelop
{
    /// <summary>
    /// Ioc自定义容器扩展
    /// </summary>
    public static class IocContainer
    {
        //私有静态(会发生突变，初始化只能做一次)
        private static IDependencyResolver _dependencyResolver;
        //单例
        private static readonly object padlock = new object();

        /// <summary>
        /// 初始化(服务集合)
        /// </summary>
        public static void Init(IServiceCollection services)
        {
            //新建容器构建器，用于注册组件和服务
            var builder = new ContainerBuilder();
            builder.Populate(services);
            //利用构建器创建容器
            Initialize(builder.Build());

            //将AutoFac设置为系统DI解析器
            //System.Web.Mvc.DependencyResolver.SetResolver(new AutofacDependencyResolver(Instance));
        }

        /// <summary>
        /// 初始化（容器）
        /// </summary>
        public static void Initialize(ILifetimeScope container)
        {
            if (_dependencyResolver == null)
            {
                lock (padlock)
                {
                    if (_dependencyResolver == null && container != null)
                    {
                        var revolver = new AutofacDependencyResolver();
                        revolver.SetContainer(container);
                        _dependencyResolver = revolver;
                    }
                }
            }
        }

        public static T Resolve<T>()
        {
            if (_dependencyResolver == null)
                return default(T);

            return FP.Try(_dependencyResolver.Resolve<T>).Run().Outcome();
        }

        public static T Resolve<T>(string serviceName)
        {
            if (_dependencyResolver == null)
                return default(T);

            return FP.Try(() => _dependencyResolver.Resolve<T>(serviceName)).Run().Outcome();
        }

        public static object Resolve(Type type)
        {
            if (_dependencyResolver == null)
                return null;

            return FP.Try(() => _dependencyResolver.Resolve(type)).Run().Outcome();
        }

        public static object Resolve(string serviceName, Type serviceType)
        {
            if (_dependencyResolver == null)
                return null;

            return FP.Try(() => _dependencyResolver.Resolve(serviceName, serviceType)).Run().Outcome();
        }
    }
}
